/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.diplomka.servicelayer.xmlconvertors;

import cz.fi.muni.diplomka.common.BuildingLevel;
import cz.fi.muni.diplomka.common.enumeration.BuildingType;
import cz.fi.muni.diplomka.common.enumeration.ResourceType;
import cz.muni.fi.diplomka.servicelayer.dto.BuildingInCity;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

/**
 * Class used for getting Building info from XML
 *
 * @author Jakub Kutil
 */
public class BuildingConvertor {

    private LocationString locationString = new LocationString();

    /**
     * Gets Building from XML
     *
     * @param buildingName name of Building to get info about
     *
     * @return building info
     */
    public BuildingInCity getBuildingFromXML(String buildingName) {

        BuildingInCity buildingInCity = new BuildingInCity();

        try {

            File fXmlFile = new File(locationString.getXMLLocation() + "\\buildings.xml");
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(fXmlFile);

            XPath xpath = XPathFactory.newInstance().newXPath();
            String expression = "/buildings/building[@id='" + buildingName + "']";
            Node node = (Node) xpath.evaluate(expression, doc, XPathConstants.NODE);

            Element element = (Element) node;

            buildingInCity.setName(BuildingType.valueOf(element.getAttribute("id")));

            Map<Integer, BuildingLevel> levels = new HashMap<>();

            for (int i = 0; i < element.getElementsByTagName("level").getLength(); i++) {
                BuildingLevel buildingLevel = new BuildingLevel();

                String expressionPrice = "/buildings/building[@id='" + buildingName + "']/level[@id='" + (i + 1) + "']";
                Node nodePrice = (Node) xpath.evaluate(expressionPrice, doc, XPathConstants.NODE);
                Element elementPrice = (Element) nodePrice;

                buildingLevel.setPriceFood(Integer.parseInt(elementPrice.getElementsByTagName("priceFood").item(0).getTextContent()));
                buildingLevel.setPriceGold(Integer.parseInt(elementPrice.getElementsByTagName("priceGold").item(0).getTextContent()));
                buildingLevel.setPriceStone(Integer.parseInt(elementPrice.getElementsByTagName("priceStone").item(0).getTextContent()));
                buildingLevel.setPriceTime(Integer.parseInt(elementPrice.getElementsByTagName("priceTime").item(0).getTextContent()));

                Map<BuildingType, Integer> requires = new HashMap<>();
                Map<ResourceType, Integer> produces = new HashMap<>();

                String expressionRequires = "/buildings/building[@id='" + buildingName + "']/level[@id='" + (i + 1) + "']";
                Node nodeRequires = (Node) xpath.evaluate(expressionRequires, doc, XPathConstants.NODE);
                Element elementRequires = (Element) nodeRequires;

                for (int j = 0; j < elementRequires.getElementsByTagName("requires").getLength(); j++) {

                    Element e = (Element) elementRequires.getElementsByTagName("requires").item(j);
                    requires.put(BuildingType.valueOf(e.getElementsByTagName("reqType").item(0).getTextContent()), Integer.parseInt(e.getElementsByTagName("reqLevel").item(0).getTextContent()));
                }

                if (!requires.isEmpty()) {
                    buildingLevel.setRequires(requires);
                }

                for (int j = 0; j < elementRequires.getElementsByTagName("produces").getLength(); j++) {

                    Element e = (Element) elementRequires.getElementsByTagName("produces").item(j);
                    produces.put(ResourceType.valueOf(e.getElementsByTagName("resource").item(0).getTextContent()), Integer.parseInt(e.getElementsByTagName("amount").item(0).getTextContent()));
                }

                if (!produces.isEmpty()) {
                    buildingLevel.setProduces(produces);
                }

                levels.put(i + 1, buildingLevel);
            }
            buildingInCity.setLevels(levels);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return buildingInCity;
    }
}
